package club.hicode.daydayup.threadlocal;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.Test;

import java.lang.ref.WeakReference;
import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * ThreadLocal测试
 *
 * @author Liu Chunfu
 * @date 2018-05-29 上午9:54
 **/
public class ThreadLocalTest1 {


    //////////// 直接饮用  ////////////
    @AllArgsConstructor
    @Data
    class Blog0 {
        private String name;
    }

    @AllArgsConstructor
    @Data
    class Writer0 {
        private Blog0 blog0;
    }

    @Test
    public void testRefer0() {
        Blog0 blog0 = new Blog0("WDF");
        Writer0 writer0 = new Writer0(blog0);

        System.out.println(writer0);
        blog0 = null;
        System.gc();
        System.out.println(writer0);
    }

    //////////// 直接饮用  ////////////

    @AllArgsConstructor
    @Data
    class Blog1 {
        private String name;
    }

    @AllArgsConstructor
    @Data
    class Writer1 {
        private WeakReference<Blog1> blog1;

        @Override
        public String toString() {
            Blog1 blog1 = this.blog1.get();
            if (blog1 != null) {
                return this.blog1.get().toString();
            }
            return "NULL";
        }
    }

    @Test
    public void testRefer1() {
        Blog1 blog1 = new Blog1("WDF");
        Writer1 writer1 = new Writer1(new WeakReference<>(blog1));

        System.out.println(writer1);
        //blog1 = null;
        System.gc();
        ThreadUtil.sleep(5, TimeUnit.SECONDS);
        System.out.println(writer1);
    }

    ////////////end

    @Test
    public void test3() {
        ThreadLocal threadLocal = new ThreadLocal();
        threadLocal.set("123");
        System.gc();
        Object o = threadLocal.get();
        System.out.println(o);
    }


    // 666
    @Test
    public void testGC1() {
        ThreadLocal threadLocal = new ThreadLocal();
        threadLocal.set(new Blog0("WDF"));

        while (true) {
            if (threadLocal.get() == null) {
                System.out.println("null");
                return;
            }
            System.gc(); //手动 GC
            System.runFinalization();
        }
    }

    // 666
    @Test
    public void testGC2() {
        WeakReference<Blog0> weakReference = new WeakReference<>(new Blog0("WDF"));

        while (true) {
            if (weakReference.get() == null) {
                System.out.println("null");
                return;
            }
            System.gc(); //手动 GC
            System.runFinalization();
        }
    }


    @Test
    public void testThreadLocal4() {
        ThreadLocal threadLocal = new ThreadLocal();
        Blog0 blog0 = new Blog0("WDF");
        threadLocal.set(blog0);

        while (true) {
            System.gc();
            System.runFinalization();
            if (threadLocal.get() == null) {
                System.out.println("success");
                return;
            }
        }
    }

    @Test
    public void testThreadLocal5() {
        Blog0 blog0 = new Blog0("WDF");
        WeakReference<Blog0> reference = new WeakReference<>(blog0);
        while (true) {
            if (reference.get() == null) {
                System.out.println("success");
                return;
            }
            System.gc();
            System.runFinalization();
        }
    }

    @Test
    public void testThreadLocal6() {
        WeakReference<Blog0> reference = new WeakReference<>(new Blog0("WDF"));
        while (true) {
            if (reference.get() == null) {
                System.out.println("NULL");
                return;
            }
            System.gc();
            System.runFinalization();
        }
    }

    @Test
    public void testOOM1() {
        //构建大对象，尽快 OOM
        List<Blog0> list = new ArrayList<>();
        List<ThreadLocal> threadLocalList = new ArrayList<>();

        for (int i = 0; i < 10000; i++) {
            list.add(new Blog0(i + "0"));
        }
        System.out.println("init success...");

        while (true) {
            ThreadLocal threadLocal = new ThreadLocal();
            threadLocal.set(list);
        }
    }

    @Test
    public void testOOM2() {
        //构建大对象，尽快 OOM
        List<Blog0> list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            list.add(new Blog0(i + "0"));
        }
        System.out.println("init suucess");
        ThreadLocal threadLocal0 = new ThreadLocal();
        threadLocal0.set(list);

        while (true) {
            ThreadLocal threadLocal = new ThreadLocal();
            threadLocal.set("xxx");
            if (threadLocal0.get() == null) {
                System.out.println("null");
            }
            //System.out.println(threadLocal0.get() == null);
        }
    }


    @Test
    public void test2() {

    }
}
